#ifndef DECIMAL_PRIVATE_H
#define DECIMAL_PRIVATE_H

#include "s21_decimal.h"

#define LONG_LAST (2 * LAST)
#define MAX_LONG_INDEX (32 * LONG_LAST - 1)
#define INIT_ZERO_S21_LONG_DECIMAL \
  {                                \
    { 0, 0, 0, 0, 0, 0, 0 }        \
  }

typedef struct {
  int bits[LONG_LAST + 1];
} s21_long_decimal;

void s21_extend(s21_decimal *source, s21_long_decimal *destination);
int s21_reduce(s21_long_decimal *source, s21_decimal *destination);

void s21_mul_long_by_ten(s21_long_decimal *value);
int s21_div_long_by_ten(s21_long_decimal *value);  // return discarded digit

int s21_get_bit(s21_decimal *value, int index);
int s21_set_bit(s21_decimal *value, int index);    // set 1
int s21_reset_bit(s21_decimal *value, int index);  // set 0
int s21_get_sign(s21_decimal *value);  // POSITIVE(+) = 0, NEGATIVE(-) = 1
int s21_set_sign(s21_decimal *value, int sing);
void s21_inverse_sign(s21_decimal *value);
int s21_get_scale(s21_decimal *value);
int s21_set_scale(s21_decimal *value, int scale);

int s21_is_invalid(s21_decimal *value);
int s21_is_valid(s21_decimal *value);
void s21_copy(s21_decimal *source, s21_decimal *distination);

int s21_get_long_bit(s21_long_decimal *value, int index);
int s21_set_long_bit(s21_long_decimal *value, int index);
int s21_reset_long_bit(s21_long_decimal *value, int index);
int s21_get_long_sign(s21_long_decimal *value);
int s21_set_long_sign(s21_long_decimal *value, int sing);
void s21_inverse_long_sign(s21_long_decimal *value);
int s21_get_long_scale(s21_long_decimal *value);
int s21_set_long_scale(s21_long_decimal *value, int scale);

void s21_copy_long(s21_long_decimal *source, s21_long_decimal *destination);
void s21_reset_long_only_bits(s21_long_decimal *value);
int s21_is_long_zero(s21_long_decimal *value);
int s21_is_not_long_zero(s21_long_decimal *value);
int s21_equalize_long_scale(s21_long_decimal *first, s21_long_decimal *second);
int s21_shift_long_bits_to_left(s21_long_decimal *value, int shift);
int s21_shift_long_bits_to_right(s21_long_decimal *value, int shift);
int s21_compare_only_long_bits(s21_long_decimal *first,
                               s21_long_decimal *second);
int s21_get_top_long_bit_index(s21_long_decimal *value);

void s21_add_long_bits_ignore_scale(s21_long_decimal *first,
                                    s21_long_decimal *second,
                                    s21_long_decimal *result);
void s21_sub_long_bits_ignore_scale(s21_long_decimal *first,
                                    s21_long_decimal *second,
                                    s21_long_decimal *result);
int s21_integer_div_long_ignore_scale(s21_long_decimal *value,
                                      s21_long_decimal *divider,
                                      s21_long_decimal *result,
                                      s21_long_decimal *remainder);

void s21_reset(s21_decimal *value);
int s21_has_long_bits(s21_long_decimal *value);
int s21_is_not_max_value_ignore_scale(s21_long_decimal *value);
void s21_increase_long_by_one(s21_long_decimal *value);
int s21_parse_int(char *string, char off_symbol, int *result);

int s21_truncate_private(s21_decimal *source, s21_decimal *destination);
void s21_increase_by_one(s21_decimal *value);

int s21_compare(s21_decimal *value_1, s21_decimal *value_2);

#endif